/************************************
 * Package: RGcpp					*
 * Authors: Rui Eduardo Gouveia Gil	*
 * Date: 2010						*
 ************************************/
#ifndef __RGCPP_CALLBACKFUNCTION_H__
#define __RGCPP_CALLBACKFUNCTION_H__

namespace rgcpp
{

template < class Class, typename ReturnType, typename P1 = void , typename P2 = void, typename P3 = void, typename P4 = void, typename P5 = void, typename P6 = void, typename P7 = void, typename P8 = void, typename P9 = void, typename P10 = void >
class CallBackFunction
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10)
		{
			return (class_instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
		};

		ReturnType execute(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10)
		{
			return operator()(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1 , typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
class CallBackFunction  < Class, ReturnType, P1, P2, P3, P4, P5, P6, P7, P8, P9 >
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2, P3, P4, P5, P6, P7, P8, P9);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9)
		{
			return (class_instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9);
		};

		ReturnType execute(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9)
		{
			return operator()(p1, p2, p3, p4, p5, p6, p7, p8, p9);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1 , typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
class CallBackFunction  < Class, ReturnType, P1, P2, P3, P4, P5, P6, P7, P8>
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2, P3, P4, P5, P6, P7, P8);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
		{
			return (class_instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8);
		};

		ReturnType execute(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
		{
			return operator()(p1, p2, p3, p4, p5, p6, p7, p8);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1 , typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
class CallBackFunction  < Class, ReturnType, P1, P2, P3, P4, P5, P6, P7>
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2, P3, P4, P5, P6, P7);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
		{
			return (class_instance->*method)(p1, p2, p3, p4, p5, p6, p7);
		};

		ReturnType execute(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
		{
			return operator()(p1, p2, p3, p4, p5, p6, p7);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1 , typename P2, typename P3, typename P4, typename P5, typename P6>
class CallBackFunction  < Class, ReturnType, P1, P2, P3, P4, P5, P6>
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2, P3, P4, P5, P6);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
		{
			return (class_instance->*method)(p1, p2, p3, p4, p5, p6);
		};

		ReturnType execute(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
		{
			return operator()(p1, p2, p3, p4, p5, p6);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1 , typename P2, typename P3, typename P4, typename P5>
class CallBackFunction  < Class, ReturnType, P1, P2, P3, P4, P5>
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2, P3, P4, P5);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
		{
			return (class_instance->*method)(p1, p2, p3, p4, p5);
		};

		ReturnType execute(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
		{
			return operator()(p1, p2, p3, p4, p5);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1 , typename P2, typename P3, typename P4>
class CallBackFunction  < Class, ReturnType, P1, P2, P3, P4>
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2, P3, P4);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2, P3 p3, P4 p4)
		{
			return (class_instance->*method)(p1, p2, p3, p4);
		};

		ReturnType execute(P1 p1, P2 p2, P3 p3, P4 p4)
		{
			return operator()(p1, p2, p3, p4);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1 , typename P2, typename P3>
class CallBackFunction  < Class, ReturnType, P1, P2, P3>
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2, P3);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2, P3 p3)
		{
			return (class_instance->*method)(p1, p2, p3);
		};

		ReturnType execute(P1 p1, P2 p2, P3 p3)
		{
			return operator()(p1, p2, p3);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1 , typename P2>
class CallBackFunction  < Class, ReturnType, P1, P2>
{

	public:

		typedef ReturnType (Class::*Method)(P1, P2);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1, P2 p2)
		{
			return (class_instance->*method)(p1, p2);
		};

		ReturnType execute(P1 p1, P2 p2)
		{
			return operator()(p1, p2);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType, typename P1>
class CallBackFunction  < Class, ReturnType, P1>
{

	public:

		typedef ReturnType (Class::*Method)(P1);

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()(P1 p1)
		{
			return (class_instance->*method)(p1);
		};

		ReturnType execute(P1 p1)
		{
			return operator()(p1);
		};

	private:

		Class*  class_instance;
		Method  method;

};

template < class Class, typename ReturnType>
class CallBackFunction  < Class, ReturnType>
{

	public:

		typedef ReturnType (Class::*Method)();

		CallBackFunction(Class* _class_instance, Method _method)
		{
			class_instance = _class_instance;
			method         = _method;
		};

		ReturnType operator()()
		{
			return (class_instance->*method)();
		};

		ReturnType execute()
		{
			return operator()();
		};

	private:

		Class*  class_instance;
		Method  method;

};

}

#endif
